﻿using ConfigHelper.Models;
using ConfigHelper.Views;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using NLog;
using System.Configuration;
using System.Data;
using System.Reflection;
using System.Windows;
using LogLevel = Microsoft.Extensions.Logging.LogLevel;

namespace ConfigHelper
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {

        public IHost _host;

        public App()
        {
            _host = Host.CreateDefaultBuilder()
                .ConfigureServices((context, services) =>
                {
                    // 使用反射注册所有服务
                    RegisterAllServices(services);
                })
                .Build();
        }

        /// <summary>
        /// 使用反射自动注册Views、ViewModels、Serves文件夹下的类
        /// </summary>
        private void RegisterAllServices(IServiceCollection services)
        {
            var assembly = Assembly.GetExecutingAssembly();

            //注册配置文件
            RegistConfig(services);

            // 注册Views
            RegisterTypesByNamespace(services, assembly, "ConfigHelper.Views");

            // 注册ViewModels
            RegisterTypesByNamespace(services, assembly, "ConfigHelper.ViewModels");

            // 注册serves
            RegisterTypesByNamespace(services, assembly, "ConfigHelper.Serves");


        }

        private void RegistConfig(IServiceCollection services)
        {
            var cfgBuilder = new ConfigurationBuilder()
              .SetBasePath(Environment.CurrentDirectory + "\\Configs")
              .AddJsonFile("appsettings.json", false, true);
            var configuration = cfgBuilder.Build();

            services.AddSingleton<IConfiguration>(configuration);
            // 实现单例注入和日志
            services.AddSingleton<IConfiguration>(configuration)
                .AddLogging(log => {
                    log.ClearProviders();
                    log.SetMinimumLevel(LogLevel.Trace);
                    log.AddNLog(); 
                });
            // 1. 获取日志参数 ILogger<T>
            var nLogConfig = configuration.GetSection("NLog");
            LogManager.Configuration = new NLogLoggingConfiguration(nLogConfig);

            services.AddOptions()
                    .Configure<RootParam>(e => configuration.Bind(e))
                    .Configure<SqlParam>(e => configuration.GetSection("SqlParam").Bind(e))
                    .Configure<SystemParam>(e => configuration.GetSection("SystemParam").Bind(e))
                    .Configure<PlcParam>(e => configuration.GetSection("PlcParam").Bind(e));
        }

        /// <summary>
        /// 根据命名空间注册类型
        /// </summary>
        private void RegisterTypesByNamespace(IServiceCollection services, Assembly assembly, string namespaceName)
        {
            var types = assembly.GetTypes()
                .Where(t => t.Namespace == namespaceName &&
                           !t.IsAbstract &&
                           !t.IsInterface &&
                           t.IsClass &&
                           !t.IsGenericType)
                .ToList();

            foreach (var type in types)
            {
                services.AddSingleton(type);
            }
        }

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            //打开主窗体
            _host.Services.GetRequiredService<MainView>().Show();


        }

        protected override void OnExit(ExitEventArgs e)
        {
            base.OnExit(e);
            _host.Dispose();
        }

    }

}
